Title Banner


Technotes


CD-ROM Driver Calls



Technote DV 22May 1993



Revised by: Chris Brown May 1994
Written by: Chris Brown, Neil Day, and Brian Bechtel May 1993

This Technical Note discusses the public interface to the Apple CD-ROM driver, which currently supports the AppleCD SC, AppleCD SC Plus/AppleCD 150, AppleCD 300, and AppleCD 300 Plus. This information supersedes the "Macintosh CD-ROM Device Driver" chapter of the AppleCD SC Developer's Guide available through APDA. If you're writing special purpose application software that needs to access the audio or data portions of a CD-ROM directly, this note will be of interest to you.

Changes since May 1993: Added new calls available in version 5.0.x of the Apple CD-ROM driver extension. Corrected some minor errors.


This Technical Note describes version 4.0.x through version 5.0.x of the Apple CD-ROM driver. Previous versions of the Apple CD-ROM driver are documented in the AppleCD SC Developer's Guide from APDA.

Version 5.x History: Version 5.0 adds support for the AppleCD 300 Plus and three new calls: DriverGestalt, ReturnDeviceIdent, and GetCDFeatures. Version 5.0 is also the first version to support asynchronous I/O using SCSI Manager 4.3. The ReadMCN and ReadISRC calls did not return the correct information in version 4.x when using an AppleCD 300. Those two calls now work in version 5.0, but the format of the returned parameters has changed for all drives. Version 5.0.1 fixes the following problems: an empty tray can be ejected using the Eject control call; when third-party SCSI accelerator cards are installed, the driver now sees the CD-ROM drives and the WhoIsThere call works correctly; DriverGestalt will no longer modify csParam[0].

Version 4.x History: Version 4.0 of the Apple CD-ROM extension was the first version to support dual-speed operation and multiple-session Photo CDs on the AppleCD 300. Version 4.0 also supports single-session Photo CDs on all other Apple CD-ROM drives. Version 4.0 had problems with certain CD-ROMs that used encryption technology to restrict access to files. When the customer was given a decryption key to gain access to a file, the file would not always appear in the Finder. Version 4.0.1 was produced to fix this problem. This version was only tested on the Macintosh IIvx and Performa 600. Version 4.0.2 was tested on all Macintosh computers. A few changes were made to ensure compatibility across the Macintosh product line. Version 4.0.2 corrected problems when sending audio commands using block addressing only. Audio calls using minute-second-frame addressing continued to work correctly.

Audio compact discs and CD-ROM discs conform to two standards, called the Red Book and the Yellow Book. The Red book specifies audio standards; the Yellow book specifies additional standards for CD-ROM. "Red Book" is the common name of the "Compact Disc Digital Audio Standard" standard, CEI IEC 908. When a disc conforms to the red book standard, it will usually have "digital audio" printed below the "disc" logo. Most music CDs conform to this standard. "Yellow Book" is the standard for CD-ROM, ISO 10149. When a disc conforms to the yellow book, it will usually say "data storage" beneath the "disc" logo.

There are several other standards usually associated with CD-ROM technology. The "Green Book" standard defines CD-I (Compact Disc Interactive); "Orange Book" defines write-once compact discs; and "Blue Book" defines CD-V (Compact Disc Video) and LaserDisc.

You can get the Red Book and Yellow Book from

ANSI

Attn: Sales

1430 Broadway

New York, NY 10018

(212) 642-4900

Red Book: CEI IEC 908

Yellow Book: ISO 10149:1989

You can get the Green Book from

American CD-I Association

11111 Santa Monica, Suite 750

Los Angeles, CA 90025

(213) 444-6619

The other standards are available only to Sony/Philips licensees. Contact Sony or Philips for licensing details.

Beginning with version 4.0 of the Apple CD-ROM software, several new Gestalt selectors are installed by Foreign File Access and various file system translators. Each selector is a version number, as defined in Inside Macintosh volume VI page VI-3-34. The list includes:

Apple Photo Access                          kpcd          
Foreign File Access                         ufox          
High Sierra File Access                     hscd          
ISO 9660 File Access, version 1.0 through   hscd          
4.0                                                       
ISO 9660 File Access, version 5.0           iscd          
Audio CD Access                             aucd          

To call the Macintosh driver, you need to understand the possible addressing formats for audio blocks on a CD. The three addressing formats are:

1) logical block

2) absolute minute, second, and frame

3) track number

An audio CD contains up to 74 minutes of sound (By decreasing the inter-track gap and other tricks, you can put more than 74 minutes of sound on a CD. Doing this is only marginally within the standard. Such CDs may not be playable on all drives.). These minutes are divided into 60 seconds. Each second contains 75 frames. There is a two second lead-in area at the beginning of the disc which contains table of contents information about the tracks on that CD. You can have a maximum of 99 tracks on a CD.

You can address sound down to the frame level; that is, down to the 1/75th of a second. You can address sound by specifying an absolute block number (e.g., start playing at absolute block 1,234,567 from the start of the disc), or by absolute minute, second, and frame number (e.g., start playing at minute 42, second 30, frame 15 on the disc) or by logical track number (e.g., start playing at track 2.)

The driver requires that the logical track number or absolute minute-second-frame numbers be specified in BCD (e.g., the decimal number 12 is stored as hex 0x0012, not as 0x000C.)

Optical Positioning Type

Many calls require an optical pick-up positioning type. This is used to specify what kind of address is being used in other parameters of a given call. There are three different optical pick-up positioning types:

Type     Description                                          
0x0000   32-bit Logical Block Address                         
0x0001   An AMIN-ASEC-AFRAME descriptor that gives the        
         running time from the beginning of the disc (in      
         BCD)                                                 
0x0002   A track number (in BCD)                              

Track Control Field

Many calls return a control field. This field describes the format of the current track, and has the following values:

Bits                                           
3210   Function                                
00x0   2 audio channels without pre-emphasis   
00x1   2 audio channels with pre-emphasis      
10x0	4 audio channels without pre-emphasis
10x1	4 audio channels with pre-emphasis
01x0	data track
01x1	reserved
11xx	reserved
xx0x	digital copy prohibited
xx1x	digital copy permitted

Audio Play Mode

Many calls require a play mode. This field describes how to play the audio track. This field has the following values:

Bits                                                  
3210   Effect                                         
0000   Muting on (no audio)                           
0001   Right channel through right channel only       
0010   Left channel through right channel only        
0011   Left and right channel through right channel   
       only*                                          
0100	Right channel through left channel only
0101	Right channel through left and right channel
0110	Right channel through left channel, left channel through right channel
0111	Right channel through left channel, left and right channel through right channel*
1000	Left channel through left channel only
1001	left channel through left channel, right channel through right channel (stereo)
1010	Left channel through left and right channel
1011	Left channel through left channel, left and right channel through right channel*
1100	Left and right channel through left channel*
1101	Left and right channel through left channel, right channel through right channel*
1110	Left and right channel through left channel, left channel through right channel*
1111	Left and right channel through left channel, left and right channel through right channel (monaural)*

*Not available on AppleCD 300 Plus                     

In the absolute minute-second-frame address, the ranges are as follows:

Minutes 00 to 99 (effectively, from 00 to 75)

Seconds 00 to 59

Frames 00 to 74

Making a High Level Driver Call

The Apple CD-ROM driver does not conform to the normal design of a driver. In particular, the Apple CD-ROM driver uses Status calls to change control settings of the device, and uses Control calls to get status information from the device. The high-level Control and Status calls weren't designed with this in mind. The glue for Control does not fill in the csParamPtr field with the results of any changes due to a Control call, and the glue for Status does not use the csParam field passed in as part of the call it creates on the stack. Do not use high level Control and Status calls to access the Apple CD-ROM driver.

Making a Low Level Driver Call

The low-level calls require that you pass in two parameters; a pointer to a parameter block and a flag indicating synchronous or asynchronous completion. For now, the driver always is synchronous, so always pass false as the second parameter. You must fill in the parameter block yourself. You may find it easier to define your own custom parameter block variants for the various calls. Some example MPW C code to get audio status information is as follows:

#include <Devices.h>
short	drvRefNum;		/* set up somewhere else */

/* this is a custom version of the CntrlParam parameter
** block defined on page II-181 and II-183 or in
** Devices.h
*/
typedef struct {
	QElemPtr	qLink;
	int		qType;
	int		ioTrap;
	Ptr		ioCmdAddr;
	ProcPtr	ioCompletion;
	OsErr		ioResult;
	StringPtr	ioNamePtr;
	int		ioVRefNum;
	int		ioRefNum;
	int		csCode;
/* Everything below this replaces: short csParam[11] */
	unsigned char	status;
	unsigned char	play;
	unsigned char	control;
	unsigned char	minute;
	unsigned char	second;
	unsigned char	frame;
	char	unused[16];		/* for the rest */
} CDCntrlParam;

/*
** GetAudioStuff
**	requires one input, the driver reference number that we
**	got by calling PBOpen().
**	fills in six parameters with appropriate information
**	from the driver call.
**	We're assuming that only one CD player is attached.
**	To generalize this code, fill in the ioVRefNum dynamically.
*/
OSErr
GetAudioStuff(status, play, control, minute, second, frame)
unsigned char	*status, *play, *control, *minute, *second, *frame;
{
	OSErr	result;
	CDCntrlParam	myPB;
	
	myPB.ioCompletion = 0;
	myPB.ioVRefNum = 1;		/* we're assuming only 1 volume */
	myPB.ioRefNum = gDrvRefNum;	/* determined elsewhere */
	myPB.csCode = 107;
	
	result = PBControl(&myPB, false);
	if (result == noErr)
	{
		*status = myPB.status;
		*play = myPB.play;
		*control = myPB.control;
		*minute = myPB.minute;
		*second = myPB.second;
		*frame = myPB.frame;
	}
	return(result);
}

Driver Summary

Name .AppleCD

Supported Control Calls

Supported Status Calls

Control Call Descriptions

KillIO (csCode=1)

The purpose of this call is to allow the interruption of all asynchronous device driver operations. This call is not supported and returns noErr if called.

Input Parameters:

csCode	1

csParam[]	Don't care.

Status Return Codes:

noErr	This is the only expected status return code.
VerifyTheDisc (csCode=5)

The purpose of this call is to ensure the validity of the data on the disc. CD-ROMs cannot be changed (they are read-only, as the name implies). When this Control call is made, as long as a disc is inserted in the drive, the CD-ROM driver will return noErr. If no disc is inserted in the drive, the CD-ROM driver will return offLinErr.

Input Parameters:

csCode	5

csParam[]	Don't care.
Status Return Codes:

noErr	The entire disc was successfully verified with no errors detected.
offLinErr	No disc inserted at the specified SCSI ID.
FormatTheDisc (csCode=6)

The purpose of this call is to format and initialize the CD-ROM disc for use in the Macintosh. However, a CD-ROM cannot be modified after it has been pressed, so this command always returns a controlErr status code.

Input Parameters:

csCode	6

csParam[]	Don't care.

Status Return Codes:

controlErr	This control call is not valid for this device.
EjectTheDisc (csCode=7)

The purpose of this call is to cause a disc eject at a specified SCSI ID. The specified SCSI device is sent a SCSI Eject Disc command to eject the disc. But first, a SCSI Prevent/Allow Medium Removal command is issued to reactivate the external Eject button on the front panel of the CD-ROM drive. If the Prevent/Allow Medium Removal command is not executed to re-allow the manual eject button, the Eject Disc command will fail with a "Check Condition" status code. The dNeedTime flag in the specified SCSI ID's DCE is set so that new disc insertions will be periodically checked for (see the accRun control call for more details). Finally, the drive queue entry associated with this drive is marked as being Off-Line and Ejected.

Input Parameters:

csCode	7

csParam[]	Don't care.
Status Return Codes:

noErr	The entire disc was successfully ejected.
offLinErr	No disc inserted at the specified SCSI ID.
GetDriveIcon (csCode=21)

The purpose of this call is to return `ICN#'-style data that is typically displayed either during the disc formatting process or by the Startup Disk Control Panel module. The drive icon is the same as the media icon in this driver. There is no true drive icon because there is no way of determining if an internal or external drive should represented. The icons always look like this:

Figure 1: Icon returned by GetDriveIcon and GetMediaIcon Control calls

Input Parameters:

csCode	21

csParam[0-10]	Don't care.

Output Produced:

csParam[0-1]	Address of ICN# and name string

Status Return Codes:

noErr	This is the only possible status return code.
GetMediaIcon (csCode=22)

The purpose of this call is to return `ICN#' -style data that is displayed whenever the disc media is shown. This icon can be seen on the desktop or when the "Get Info" (Cmd-I) command from the Finder is executed under System 7. See figure 1 for a picture of the icon returned.

Input Parameters:

csCode	22

csParam[0-10]	Don't care.

Output Produced:

csParam[0-1]	Address of ICN# and name string

Status Return Codes:

noErr	This is the only possible status return code.
DriveInfo (csCode=23)

The purpose of this call is to return information describing drive characteristics for the specified SCSI ID. The values to be returned are defined in Inside Macintosh, volume V, pages 470-471. The value returned by the Apple CD-ROM driver is $0000 $0B01. The low order byte indicates unspecified drive type. The high order byte of the low word indicates external drive (this is set even if the drive is actually mounted internally), SCSI drive, removable drive, and secondary drive.

Input Parameters:

csCode	23

csParam[0-10]	Don't care.

Output Produced:

csParam[0] (word)	$0000
csParam[1] (word)	$0B01

Status Return Codes:

noErr	This is the only possible status return code.
accRun (csCode=65)

There is no need for an application to issue this call. This call is made on a regular basis by the operating system, based on the dNeedsTime flag in the dCtlFlags entry in the Device Control Entry (DCE) for the Apple CD-ROM driver. The purpose of this call is to perform operations required by the driver on an "as needed" basis. Since the CD-ROM device is a removable media device and does not generate interrupts when a disc is inserted, the only way to detect the fact that a disc has been inserted is to occasionally poll all devices that the driver last determined did not have a disc inserted. Almost all Macintosh programs make a call to the MacOS routine SystemTask(), and one of the functions of that routine is to occasionally make some CPU time available to all devices that request it. This is done by setting the dNeedTime flag in the Device Control Entry (DCE) for a given device.

Testing for disc insertions is the main function provided by this Control call. accRun also handles some other functions on a one-time basis. During the Macintosh boot process if the driver is installed before the System file is read in, the driver cannot install its custom CD-ROM Disk Switch subroutine. This is because when the System file is read in and installed it will overwrite the low memory global that defines the address of the standard Disk Switch routine. So, the installation of our custom Disk Switch routine is held off until the first invocation of SystemTask() to make sure that the System file has already been loaded and the standard Disk Switch routine has been initialized.

Input Parameters:

csCode	65

csParam[]	Don't care.

Status Return Codes:

noErr	This is the only possible status return code.
ModifyPostEvent (csCode=76)

The purpose of this call is to allow an application to modify the driver's behavior when non-HFS discs are inserted into the CD-ROM drive. The default action of the driver is to post a disc-inserted event for all discs that are inserted into the CD-ROM drive, regardless of whether or not the disc actually contains valid partition information and HFS file system. There may be some reason why the driver should not post the disc-inserted event and this call allows that "feature" to be turned off. When this feature is turned off for a specified SCSI ID, it will stay off until it is reactivated (via another call to ModifyPostEvent) or until the machine is restarted.

Input Parameters:

csCode	76

csParam[0]	0	Do not issue disc-insert events for non-HFS CD-ROMs
	!= 0	Issue disc-insert events for non-HFS CD-ROM discs
csParam[1-10]		Reserved for future use - must be zero (0).

Status Return Codes:

noErr		This is the only possible status return code.
ChangeBlockSize (csCode=79)

The purpose of this call is to allow an application to modify the "block size" the drive is currently using to read data with. The standard HFS file system block size is 512 bytes/block. Applications and file system translators dealing with non-HFS file systems may require other block sizes to read their data correctly. The Apple CD SC can handle block sizes of 256, 512, 1024, 2048, 2336 and 2340 bytes. In addition, the CD SC Plus drive can handle a block size of 2056 bytes. In addition, the CD 300 and CD 300 Plus can handle block sizes of 2352, 2646, and 2647. The CD 300 and CD 300 Plus cannot handle a block size of 256.

For those block sizes greater than 2048 bytes, special consideration is given to the DCR bit in the Error Recovery Parameters page to enable/disable layered ECC. For the CD SC, the bit is set to 1 to disable ECC. Without this, accessing Mode 2 data blocks with a block size greater than 2048 would create a Check Condition error response by the drive. For all other drives, if there is a CD-I or XA disc inserted, the ECC will be enabled. For all other discs or if there is no media inserted, the ECC will be turned off. The following tables show the type of data that is returned for each of the valid block sizes:

CD-ROM Mode 1 Data Format:

  Block     Block Contents (size in bytes)                                     
   Size                                                                        
 (bytes)                                                                       
   256      User data (256)                                                    
   512      User data (512)                                                    
   1024     User data (1024)                                                   
   2048     User data (2048)                                                   
   2336     User data (2048) + EDC (4) + Zero (8)                              
   2340     Header (4) + User data (2048) + EDC (4) + Zero (8) + ECC (276)     
   2352     Sync (12) + Header (4) + User data (2048) + EDC (4) + Zero (8) +   
            ECC (276)                                                          

CD-ROM Mode 2 Data Format:

  Block     Block Contents (size in bytes)                                     
   Size                                                                        
 (bytes)                                                                       
   2336     Mode 2 User data (2336)                                            
   2340     Header (4) + Mode 2 User data (2336)                               
   2352     Sync (12) + Header (4) + Mode 2 User data (2336)                   

CD-ROM Mode 2 Form 1 Data Format (CD-XA or CD-I):

  Block     Block Contents (size in bytes)                                     
   Size                                                                        
 (bytes)                                                                       
   256      User data (256)                                                    
   512      User data (512)                                                    
   1024     User data (1024)                                                   
   2048     User data (2048)                                                   
   2056     Subheader (8) + User data (2048)                                   
   2336     Subheader (8) + User data (2048) + EDC (4) + ECC (276)             
   2340     Header (4) + Subheader (8) + User data (2048) + EDC (4) + ECC      
            (276)                                                              
   2352     Sync (12) + Header (4) + Subheader (8) + User data (2048) + EDC    
            (4) + ECC (276)                                                    
   2646     Sync (12) + Header (4) + Subheader (8) + User data (2048) + EDC    
            (4) + ECC (276) + Byte Error Flags (294)                           
   2647     Sync (12) + Header (4) + Subheader (8) + User data (2048) + EDC    
            (4) + ECC (276) + Block Error Flag (1) + Byte Error Flags (294)    

CD-ROM Mode 2 Form 2 Data Format (CD-XA or CD-I):

  Block     Block Contents (size in bytes)                                     
   Size                                                                        
 (bytes)                                                                       
   2336     Subheader (8) + User data (2324) + Reserved or EDC (4)             
   2340     Header (4) + Subheader (8) + User data (2324) + Reserved or EDC    
            (4)                                                                
   2352     Sync (12) + Header (4) + Subheader (8) + User data (2324) +        
            Reserved or EDC (4)                                                
   2646     Sync (12) + Header (4) + Subheader (8) + User data (2324) +        
            Reserved or EDC (4) + Byte Error Flags (294)                       
   2647     Sync (12) + Header (4) + Subheader (8) + User data (2324) +        
            Reserved or EDC (4) + Block Error Flag (1) + Byte Error Flags      
            (294)                                                              

Input Parameters:

csCode	79

csParam[0]	Block size the drive should use from now on
csParam[1-10]	Reserved for future use - must be zero (0).

Status Return Codes:

noErr	The block size change completed successfully.
paramErr	An invalid block size was specified.
UserEject (csCode=80)

The control call UserEject enables or disables the eject button on the drive. This call provides a method to disable/enable the manual eject button for a specified SCSI ID. Global variables are maintained for each SCSI ID that reflect the current state of the manual eject button. If the button is enabled, the driver sets the dNeedTime flag in the appropriate DCE, telling the driver to periodically poll the device to see whether a disc has been ejected, or inserted. This is the only way the driver has to ensure the validity of its global variables in this situation. When a disc is inserted, the button setting reverts back to the default setting.

Input Parameters:

csCode	80

csParam[0]	1	Enable the manual eject button. 
	!= 1	Disable the manual eject button. {default}
csParam[1-10]		Reserved for future use - must be zero (0).

Status Return Codes:

noErr	The button was successfully enabled/disabled.
offLinErr	No disc inserted in the drive.
SetPollFreq (csCode=81)

The purpose of this call is to allow an application to specify a different polling frequency (in Macintosh time ticks) than the driver default value (120). This polling frequency is the value used for determining how often the accRun Control call is issued, as well as the polling frequency for a VBL task that is started during the execution of the driver's custom Disk Switch routine.

Input Parameters:

csCode	81

csParam[0]	Number of Macintosh ticks to be used for polling frequency
csParam[1-10]	Reserved for future use - must be zero (0).

Status Return Codes:

noErr	This is the only possible status return code.
ReadTOC (csCode=100)

The purpose of this call is to allow an application to receive various types of Table Of Contents (TOC) data from the drive. There are six varieties of the ReadTOC call.

For transfer types 1, 2, and 5, the TOC information is returned directly in the caller's csParam[] array. For types 3, 4, and 6, the caller is required to specify a buffer to place the information into. In the case of a type 4 transfer, the buffer must be 512 bytes long.

Input Parameters:

csCode	100

For Type 1:

csParam[0]	The transfer type value 1.
csParam[1-10]	Reserved for future use - must be zero (0).

For Type 2:

csParam[0]	The transfer type value 2.
csParam[1-10]	Reserved for future use - must be zero (0).

For Type 3:

csParam[0]	The transfer type value 3.
csParam[1-2]	The address of a buffer to return the requested information. 
csParam[3]	The size of the buffer specified in csParam[1-2], in bytes.
csParam[4]	The MSByte (the upper 8 bits) of this 16-bit word must contain the starting track number, in BCD.

For Type 4 (Not available on CD SC):

csParam[0]	The transfer type value 4.
csParam[1-2]	The address of a buffer to return the requested information. 

For Type 5 (CD 300 & CD 300 Plus Only):

csParam[0]	The transfer type value 5.
csParam[1-10]	Reserved for future use - must be zero (0).

For Type 6 (CD 300 & CD 300 Plus Only):

csParam[0]	The transfer type value 6.
csParam[1-2]	The address of a buffer to return the requested information. 
csParam[3]	The size of the buffer specified in csParam[1-2], in bytes.
csParam[4]	The MSByte (the upper 8 bits) of this 16-bit word must contain the starting session number, in BCD.

Output Produced:

Type 1:

csParam[0]:15-8	MSByte contains first user track number (in BCD)
csParam[0]:7-0	LSByte contains last user track number (in BCD)

Type 2:

csParam[0]:15-8	MSB contains the MIN field of a MIN-SEC-FRAME descriptor that describes the Lead Out starting address (in BCD).
csParam[0]:7-0	LSB contains the SEC field of the Lead Out starting address descriptor.
csParam[1]:15-8	MSB contains the FRAME field of the Lead Out starting address descriptor.

Type 3:

  1. The user must specify a return buffer address and the size of the buffer. The buffer is filled with 4-byte entries for each track in the requested range. Each entry is of the form:

Entry (byte offset) Contents

0 Bits 7-4: Reserved

	Bits 3-0:	Control Field (see Track Control Field at the beginning of this document for more information)
1 The MIN field of a MIN-SEC-FRAME descriptor that describes the start of the

associated track.

2 The SEC field of the track starting address descriptor.

3 The FRAME field of the track starting address descriptor.

  1. Note: no entries will be returned for data tracks on CD-I discs.
Type 4:

  1. This option is not valid for the CD SC drive. The user must specify a return buffer address. The buffer must be 512 bytes long, and is filled with the entire table of contents, which is returned in the form:
	Entry (byte offset)	Contents
	0	Reserved.
	1-5	TOC entry for point A0 (first track number).
	6-10	TOC entry for point A1 (last track number).
	11-15	TOC entry for point A2 (address of beginning of lead out area).
	16-20	TOC entry for track 1.
	.	.
	.	.
	.	.
	506-510	TOC entry for track 99.

Each five byte entry is of the form:

Entry (byte offset)	Contents
0	Bits 7-4: Reserved
	Bits 3-0: Control Field (see Track Control Field at the beginning of this document for more information)
1	Point or track number.
2	PMIN.
3	PSEC.
4	PFRAME.

Type 5 (CD 300 & CD 300 Plus Only):

csParam[0]	The first session number (in BCD).
csParam[1]	The last session number (in BCD).
csParam[2]	First track number of last session (in BCD).
csParam[3]:15-8	Bits 7-4: Reserved
	Bits 3-0: Control Field of first track in last session. (see Track Control Field at the beginning of this document for more information)
csParam[3]:7-0	The MIN field of a MIN-SEC-FRAME descriptor that describes the start of the first track of the last session (in BCD).
csParam[4]:15-8	The SEC field of the track starting address descriptor (in BCD).
csParam[4]:7-0	The FRAME field of the track starting address descriptor (in BCD).

Type 6 (CD 300 & CD 300 Plus Only):

  1. The user must specify a return buffer address and the size of the buffer. The buffer is filled with a 4-byte header and 8-byte entries for each Q-subcode entry in the requested range. The first three entries are for points A0, A1 and A2 and are followed by the track entries for that session. After that, the Q-subcode entries are sorted in ascending order using the ADR field and within each ADR group by ascending order of the POINT field. This pattern is repeated for each session on the disc.

The 4-byte header is of the form:

Header (byte offset) Contents

0-1 Total number of TOC data bytes transferred excluding these two length bytes.

2 First session number on the disc (in BCD).

3 Last session number on the disc (in BCD).

Each TOC entry is of the form:

Entry (byte offset) Contents

0 The session number (in hex).

1 Bits 7-4: ADR field, i.e., Q-subcode mode field

Bits 3-0: Control Field (see Track Control Field at the beginning of this document for more information)

2 TNO - Track number.

3 POINT. In some early CD-300 units, the values for Entries 2 and 3 are swapped. This is due to a firmware bug, which was corrected on later drives. You should always OR the two values together to always receive the proper value.

4 MIN.

5 SEC.

6 FRAME.

7 ZERO.

8 PMIN.

9 PSEC.

10 PFRAME.

  1. The values come directly from the disc and will be in either BCD or hexadecimal format depending on the field. The session number, ADR/Control and POINT fields are in hexadecimal. All other fields are in BCD. For more information on the format of the TOC, please refer to the "Yellow Book" specification for CD-ROM discs, ISO 10149.

Status Return Codes:

noErr	TOC data successfully retrieved.
paramErr	An invalid TOC type specified. This can happen due to the TOC type being out of range, or due to the call not being supported by the drive in question (e.g. type 6 call issued to AppleCD SC drive.)
offLinErr	No disc in drive.
ReadQ (csCode=101)

The purpose of this call is to allow an application access to the Q-subcode information for the current track. The current track is the track that the optical pickup is currently over on a disc.

Input Parameters:

csCode	101

csParam[0-10]	Unused on input. Q-subcode data are returned here.

Output Produced:

csParam[0]:[15-8]	MSB contains Control Field information. (see Track Control Field at the beginning of this document for more information)
csParam[0]:[7-0]	LSB contains current track number (in BCD).
csParam[1]:[15-8]	MSB contains the current index number in the current track.
csParam[1]:[7-0]	LSB contains the MIN field of a MIN-SEC-FRAME descriptor, which describes the relative running time from the beginning of the track.
csParam[2]:[15-8]	MSB contains the SEC field for a MIN-SEC-FRAME descriptor.
csParam[2]:[7-0]	LSB contains the FRAME field for a MIN-SEC-FRAME descriptor.
csParam[3]:[15-8]	MSB contains the AMIN field of an AMIN-ASEC-AFRAME descriptor, which describes the relative running time from the beginning of the disc.
csParam[3]:[7-0]	LSB contains the ASEC field of an AMIN-ASEC-AFRAME descriptor.

csParam[4]:[15-8]	MSB contains the AFRAME field of an AMIN-ASEC-AFRAME descriptor.
csParam[4]:[7-0]	LSB unused.

Status Return Codes:

noErr	Q-subcode data successfully retrieved.
ReadHeader (csCode=102)

The control call ReadHeader returns the absolute minute-second-frame address and CD-ROM mode information about a specified logical block. If a requested block is within an audio track (CD-DA) of the disc, a paramErr will be returned.

Input Parameters:

csCode	102

csParam[0-1]	32-bit logical block address to retrieve Header information for.
csParam[2-10]	Reserved for future use - must be set to zero.

Output Produced:

csParam[0]:[15-8]	MSB contains the AMIN field of an AMIN-ASEC-AFRAME descriptor, which describes the absolute running time from the beginning of the disc. Value is in BCD format.
csParam[0]:[7-0]	LSB contains the ASEC field of an AMIN-ASEC-AFRAME descriptor. Value is in BCD format.
csParam[1]:[15-8]	MSB contains the AFRAME field of an AMIN-ASEC-AFRAME descriptor. Value is in BCD format.
csParam[1]:[7-0]	LSB contains the CD-ROM data mode of the logical block which defines what type of data will be within the 2048 data bytes and 288 auxiliary bytes of the logical block:
Data Mode   User Data Field   10x101x001x111xx  
              (2048 bytes)    xx0x010101100111  
                              1000100110101011  
                              110011011110Auxi  
                                liary Field     
                                (288 bytes)     
    0       all bytes zero    all bytes zero    
    1       user data         EDC, L-EC bytes   
    2       user data         user data         

Status Return Codes:

noErr	Header information successfully retrieved.
AudioTrackSearch (csCode=103)

The purpose of this call is to position the optical pick-up at the specified audio address. In addition, you can also tell the drive either to start to play at the given address, or to pause at this address until an AudioPlay command is executed and in what Play Mode it should output the audio information in.

Input Parameters:

csCode	103

csParam[0]	The optical pick-up positioning address type (see "Optical Positioning Types" at the beginning of this document for more information.)
csParam[1-2]	32-bit value representing the search address required by the corresponding type value in csParam[0] (see above).
csParam[3]	A boolean value indicating what the drive should do when positioning of the pick-up is complete:
		0	Enter a Hold Track state ("pause")
		!= 0	Start playing the audio track, according the specified Play Mode.
csParam[4]	The "Play Mode" . (see "Audio Play Modes" at the beginning of this document for more information.)
csParam[5-10]	Reserved for future use - must be set to zero.

Status Return Codes:

noErr	Optical pick-up successfully positioned.
paramErr	Invalid type, Play Mode or Search Address value specified.
AudioPlay (csCode=104)

The purpose of this call is to position the optical pick-up at the specified audio address and begin playback of the audio at that address. It can be similar to the AudioTrackSearch command that automatically begins playing at the specified Search Address (see the documentation on the AudioTrackSearch call for more detail.) However, this command can also be used to specify a "Stop Address". The use for this would be to position the optical pick-up with an AudioTrackSearch command to indicate the starting position to begin playback and then specify where the playback should stop by issuing an AudioPlay command to mark the stopping address. Playback then continues from the position originally marked by AudioTrackSearch until the position indicated by AudioPlay.

Input Parameters:

csCode	104

csParam[0]	The optical pick-up positioning address type (see "Optical Positioning Types" at the beginning of this document for more information.)
csParam[1-2]	32-bit value representing the search address required by the corresponding type value in csParam[0].
csParam[3]	A boolean value indicating whether the address specified in csParam[1-2] is a starting address or a stopping address.
		0	The address specified is a Starting Address.
		!= 0	The address specified is a Stopping Address.
csParam[4]	The "Play Mode" (see "Audio Play Modes" at the beginning of this document for more information.)
csParam[5-10]	Reserved for future use - must be set to zero.

Status Return Codes:

noErr	Operation successful.
paramErr	Invalid type, Play Mode or Search Address value specified.
AudioPause (csCode=105)

The purpose of this call is to cause the CD-ROM drive to either enter a Hold Track ("Pause") or Play state. This command is only valid after the issuance of an Audio Track Search, or Audio Play command.

Input Parameters:

csCode	105

csParam[0-1] (long)	A boolean value that tells the CD-ROM drive either to pause or continue.
		0	Release the "pause" state and continue playing at 		the same Q-subcode address before the last 
			AudioPause.
		1	Enter a Hold Track ("Pause") state.
 csParam[2-10]	Reserved for future use - must be set to zero.

Status Return Codes:

noErr	CD-ROM device successfully paused or released from pause.
paramErr	Invalid pause value specified.
AudioStop (csCode=106)

The purpose of this call is to specify an address to the CD-ROM drive at which it should end the current Play operation.

Input Parameters:

csCode	106

csParam[0]	The optical pick-up positioning address type (see "Optical Positioning Types" at the beginning of this document for more information.)
csParam[1-2]	32-bit value representing the search address required by the corresponding type value in csParam[0].
csParam[3-10]	Reserved for future use - must be set to zero.

Status Return Codes:

noErr	Optical pick-up successfully positioned.
paramErr	Invalid type or Search Address value specified.
AudioStatus (csCode=107)

The purpose of this call is to return the current audio play status information and the starting Q- subcode address for the current track. The audio play status information includes the Play Mode, and Status and Control information for the current track.

Input Parameters:

csCode	107

csParam[0-10]	Unused on input. Audio Status data are returned here.

Output Produced:

csParam[0]:15-8	The MSB contains the Status Field.
	0	Audio Play operation in progress
	1	CD-ROM device currently in Hold Track ("Pause") state
	2	MUTING-ON operation in progress
	3	Audio Play completed
	4	Error occurred during audio play operation
	5	Audio play operation not requested
csParam[0]:7-4	Reserved.
csParam[0]:3-0	Play Mode. (see "Audio Play Modes" at the beginning of this document for more information.)
csParam[1]:15-12	Reserved.
csParam[1]:11-8	The LSNibble contains the Control Field.(see Track Control Field at the beginning of this document for more information)
csParam[1]:7-0	The LSB contains the AMIN field of an AMIN-ASEC-AFRAME descriptor that describes the current Q-subcode.
csParam[2]:15-8	The MSB contains the ASEC field of an AMIN-ASEC-AFRAME descriptor for the current Q-subcode.
csParam[2]:7-0	The LSB contains the AFRAME field of an AMIN-ASEC-AFRAME descriptor for the current Q-subcode.

Status Return Codes:

noErr	Status information successfully read.
offLinErr	No disc in drive.
controlErr	An error occurred in the Audio Status command execution.
AudioScan (csCode=108)

The purpose of this call is to request the CD-ROM drive to perform a fast-forward or fast-reverse operation starting from a specified address.

Input Parameters:

csCode	108

csParam[0]	The optical pick-up positioning address type (see "Optical Positioning Types" at the beginning of this document for more information.)
csParam[1-2]	32-bit value representing the search address required by the corresponding type value in csParam[0].
csParam[3]	The direction the scan should take place:
		0	Scan in the fast-forward direction
		!= 0	Scan in the fast-reverse direction
csParam[4-10]	Reserved for future use - must be set to zero.

Status Return Codes:

noErr	Optical pick-up successfully positioned.
paramErr	Invalid type or Search Address value specified.
AudioControl (csCode=109) [not available on AppleCD SC]

The purpose of this call is to set the output volume for the drive's audio channels. Each channel can be given a value from zero to 255, zero indicating that the channel output is muted, 255 indicating maximum volume. Beginning with driver version 4.0.5, the volume level is saved in the driver and will be restored when the Macintosh is powered on. Note that this command is not available on the CD SC.

Input Parameters:

csCode	109

csParam[0]:15-8	MSB Left channel volume (0-FFh).
csParam[0]:7-0	LSB Right Channel volume (0-FFh).
csParam[1-10]	Reserved for future use - must be set to zero.

Status Return Codes:

noErr	Audio volume successfully set.
paramErr	on AppleCD SC, this call is not supported.
ReadMCN (csCode=110) [not available on AppleCD SC]

The purpose of this call is to allow an application access to the Media Catalog Number for the disc. The Media Catalog Number consists of the UPC/Bar Code information for the disc. The output format was changed from binary data to a pascal string beginning with driver version 5.0. Applications can check the upper bit of csParam[0] for the MCVal bit. If set, the application can use the version 4.0 output format. If the MCVal is not set but the upper byte in csParam[0] is not equal to zero, then the application can use the version 5.0 output. Note: Driver version 4.0.x does not return the correct MCN data when using an AppleCD 300.

Input Parameters:

csCode		110

csParam[0-10]		Unused on input. MCN data are returned here.

Output Produced (version 5.0):

csParam[0-6]:	Pascal string containing the MCN (UPC/Bar Code). If the string length (upper eight bits of csParam[0]) is zero, an MCN was not found on the disc.

Output Produced (version 4.0):

csParam[0]:[15-8]	MSB contains MCVal bit (bit 15). If this bit is set to one, then the Media Catalog Number data was found and the rest of the returned fields are valid. If this bit is set to zero, then the Media Catalog Number data was not found and the rest of the returned fields are invalid.
csParam[0]:[7-0]	LSB contains MSB of the Media Catalog Number (UPC/Bar Code) data if the MCVal bit is set.
csParam[1-7]	Contains the rest of the Media Catalog Number (UPC/Bar Code) data if the MCVal bit is set. The LSB of csParam[7] contains the LSB of the Media Catalog Number data.

Status Return Codes:

noErr	Media Catalog Number data successfully retrieved or no MCN was found on the disc.
ReadISRC (csCode=111) [not available on AppleCD SC]

The purpose of this call is to allow an application access to the International Standard Recording Code information for a specified track on a disc. For more information about the ISRC, please refer to ISO 10149. The output format was changed from binary data to a pascal string beginning with driver version 5.0. Applications can check the upper bit of csParam[0] for the TCVal bit. If set, the application can use the version 4.0 output format. If the TCVal is not set but the upper byte in csParam[0] is not equal to zero, then the application can use the version 5.0 output. Note: Driver version 4.0.x does not return the correct ISRC data when using an AppleCD 300.

Input Parameters:

csCode		111

csParam[0]		A track number (in BCD).
csParam[1-10]		Unused on input. ISRC data are returned here.

Output Produced (version 5.0):

csParam[0-6]:	Pascal string containing the ISRC. If the string length (upper eight bits of csParam[0]) is zero, an ISRC was not found for the specified track.

Output Produced (version 4.0):

csParam[0]:[15-8]	MSB contains TCVal bit (bit 15). If this bit is set to one, then the ISRC data was found for the specified track and the rest of the returned fields are valid. If this bit is set to zero, then the ISRC data was not found for the specified track and the rest of the returned fields are invalid.
csParam[0]:[7-0]	LSB contains MSB of the ISRC data for the specified track if the TCVal bit is set.
csParam[1-7]	Contains the rest of the ISRC data if the TCVal bit is set. The LSB of csParam[7] contains the LSB of the ISRC data.

Status Return Codes:

noErr			ISRC data successfully retrieved.
ReadAudioVolume (csCode=112) [not available on AppleCD SC]

The purpose of this call is to return the current audio volume control data for the drive. This call is not available on the CD SC.

Input Parameters:

csCode	112

csParam[0-10]	Unused on input. Audio Volume data are returned here.

Output Produced:

csParam[0]:15-8	The MSB contains the left channel volume (0-FFh).
csParam[0]:7-0	The LSB contains the right channel volume (0-FFh).

Status Return Codes:

noErr	Status information successfully read.
offLinErr	No disc in drive.
ioErr	An error occurred in the ReadAudioVolume command execution.
GetSpindleSpeed (csCode=113)

The purpose of this call is to return the current rotational speed of the drive. This call always returns 00 on the Apple CD SC and AppleCD SC Plus/CD 150.

Input Parameters:

csCode	113

csParam[0-10]	Unused on input. Speed information is returned here.

Output Produced:

csParam[0]:	The current rotational speed:
	00	= Normal speed
	FF	= Maximum speed (AppleCD 300 and AppleCD 300 Plus only)

Status Return Codes:

noErr	Speed information successfully read.
ioErr	An error occurred in the GetSpindleSpeed command execution.
SetSpindleSpeed (csCode=114)

The purpose of this call is to set the rotational speed of the drive. This call will return paramErr for an AppleCD SC or AppleCD SC Plus/CD 150 if the input parameter is not 00 (normal speed.)

Input Parameters:

csCode	114

csParam[0]	Speed setting:
		00 = Normal speed (i.e. 150 KB/sec)
		FF = Maximum speed (i.e. 300 KB/sec)
csParam[1-10]	Reserved for future use - must be set to zero.

Status Return Codes:

noErr	Rotational speed successfully set.
paramErr	An invalid speed setting was specified.
ioErr	An error occurred in the SetSpindleSpeed command execution.
ReadAudio (csCode=115) [AppleCD 300 and AppleCD 300 Plus only]

The purpose of this call is to read digital audio and/or subcode data from the disc into a specified buffer. The starting audio address may be specified in one of three formats (see the "Audio Play Modes" at the beginning of this document for more information.) There are four possible formats for the audio data that is returned:

Type values	Description
0	Audio data only --2352 bytes per audio block.
1	Audio data with Q-subcode--2352 audio bytes, 10 bytes Q-                                                
subcode, and 6 zero bytes = 2368 bytes per block. 
2	Audio data with all subcode data (P~W)--2352 audio bytes and 96 subcode bytes = 2448 bytes per block.
3	All subcode data only (P~W)--96 subcode bytes per block.

The position of an audio block cannot be determined exactly. Thus, two ReadAudio calls with the same starting address will not necessarily return the same data in the same position. Typically the data will be shifted up to 1.5 frames (3528 bytes). To read large sections of audio data using multiple ReadAudio calls and not have a gap are overlap in the audio data, the ReadAudio calls must occur frequently enough to prevent the internal drive buffer from overflowing. If the Macintosh is too slow, a controlErr will be returned along with the audio data. The controlErr indicates that the audio data just received has a gap or overlap in it.

For type 2 and type 3, the P and Q-subcodes are accurately aligned to the CD block boundary, but the R through W subcodes may be offset by one pack (i.e. 24 subcode bytes) from the P and Q-subcodes. Thus, in any 96-byte subcode data from block n, the last 24 bytes contain R through W subcodes from the next block (n+1).

The current volume setting has no effect on the audio data that is returned. When using ReadAudio with type 3, the audio is played through any connected speakers. The audio can be muted to avoid hearing anything while reading the subcode data. For types 0, 1, and 2 the data rate can be adjusted by changing the drive speed prior to calling ReadAudio. For type 3 only, subcode data is always transferred at an average throughput of 150 KBytes per second.

Input Parameters:

csCode	115

csParam[0]	Audio Type (see above)
csParam[1-2]	The address of the buffer to return the requested information.
csParam[3]	The starting address type (see "Optical Positioning Types" at the beginning of this document for more information.)
csParam[4-5]	32-bit value representing the start address required by the corresponding type value in csParam[3]. 
csParam[6]	The number of consecutive audio blocks to return.
csParam[7-10]	Reserved for future use - must be set to zero.

Status Return Codes:

noErr	Audio data successfully retrieve.
paramErr	An invalid audio type, address type, or audio address specified.
controlErr	An error occurred in the ReadAudio command execution.
ReadAllSubcodes (csCode=116) [AppleCD 300 and AppleCD 300 Plus only]

The purpose of this call is to read consecutive blocks of subcode information (P~W) as the drive is playing audio. When one of the commands is issued that begins playing audio, the subcode information corresponding to the audio blocks is stored in a buffer within the drive. ReadAllSubcodes retrieves the subcode information from this buffer. If the number of subcode blocks requested exceeds the quantity currently in the buffer, the control call waits until more subcode blocks are available before returning. An option allows any subcode data currently in the buffer to be purged, allowing the host to re-synchronize to the latest subcode data. This call is only available on the CD 300 and CD 300 Plus.

If the Macintosh does not send ReadAllSubcode requests frequently enough, a controlErr will be returned indicating that the internal drive buffer overflowed and some subcode data was lost. A ReadAllSubcodes call must be made with the purge parameter set to clear the overflow condition.

Note: The R through W subcodes that are returned are accurately aligned to the CD block boundary, but the P and Q subcodes may be offset by one pack (i.e. 24 subcode bytes) from the R through W subcodes. Thus, in any 96-byte subcode data from block n, the first 24 bytes may contain the P and Q subcodes from the previous block (n-1).

Input Parameters:

csCode	116

csParam[0-1]	The address of the buffer to return the requested subcode blocks.
csParam[2]	A boolean value indicating if the current subcode information in the drive buffer should be purged before retrieving any subcode data. 
	0 	retrieve buffered subcode blocks
	!= 0	delete any blocks in the subcode buffer & wait for new 
		data 
csParam[3]	The number of consecutive subcode blocks (96 bytes per block) to return. 
csParam[4-10]	Reserved for future use - must be set to zero.

Status Return Codes:

noErr	Audio data successfully retrieve.
controlErr	An error occurred in the ReadAllSubcodes command execution.

Status Call Descriptions

DriveStatus (csCode=8)

The purpose of this call is to return information about the drive/disc as described in Inside Macintosh, Volume II, page 215.

Input Parameters:

csCode	8

csParam[0-10]	Not defined on entry. On exit, contains information that maps to the DrvSts record/structure.

Status Return Codes:

noErr	This is the only possible status return code.
DriveGestalt (csCode=43)

The purpose of this call is to return Gestalt type information for the driver itself. Currently defined driverGestalt selectors are:

driverGestaltSyncResponse = 'sync'; /* True if driver only behaves synchronously.  */
driverGestaltVersResponse = 'vers';	/* The version number of the driver (First	    */
					/* 4 bytes of the vers #1 resource).           */
driverGestaltIntfResponse = 'intf';	/* Physical interface to device.               */
driverGestaltDevTResponse = 'devt';	/* Type of device the driver is driving.       */
driverGestaltDevTResponse = 'boot'; /* PRAM value to designate this driver/drive.  */
					/* Valid only when SCSI Manager 4.3 is active. */

The following response buffers are defined for the driverGestalt selectors:

struct driverGestaltSyncResponse
{
	Boolean	behavesSynchronously;	/* true/false = sync/async */
};
typedef struct driverGestaltSyncResponse driverGestaltSyncResponse

struct driverGestaltVersResponse
{
	NumVersion driverVersion;
};
typedef struct driverGestaltVersResponse driverGestaltVersResponse

struct driverGestaltIntfResponse
{
	OSType	interfaceType;	/* 'scsi' */
};
typedef struct driverGestaltIntfResponse driverGestaltIntfResponse

struct driverGestaltDevTResponse
{
	OSType	deviceType;		/* 'cdrm' */
};
typedef struct driverGestaltDevTResponse driverGestaltDevTResponse

typedef struct
{
	unsigned char	extDev;	/* Packed target (upper 5 bits) */	
					/* LUN (lower 3 bits)           */
	unsigned char	partition;	/*  Unused                      */
	unsigned char	SIMSlot;	/*  Slot                        */
	unsigned char	SIMsRSRC;	/*  sRsrcID                     */
} driverGestaltBootResponse;

Input Parameters:

csCode	43

csParam[0]	driverGestaltSelector
csParam[1-10]	Reserved for future use - must be set to zero

Output Produced:

csParam[1]:	driverGestaltResponse

Status Return Codes:

noErr	This is the only possible status return code.
Get2KOffset (csCode=95)

The purpose of this call is to return information to the caller that allows subsequent Prime calls to be aligned to the 2K physical block size of the CD-ROM. This can be used in applications (e.g. QuickTime) to increase streaming performance by avoiding data requests that span across a 2K disc block. This call returns the number of bytes between the beginning of the 2K physical block and the first byte read in the previous Prime call. Possible values are 0, 512, 1024, and 1536. For example, if a Prime call causes a read of the last 512 bytes within a 2K physical block, this call will return 3 x 512 = 1536 bytes. This is the offset from the beginning of the 2K block to the start of the first data byte read. Note that this call assumes that the file system actually makes a Prime call and that a file system cache did not fill the read request.

Input Parameters:

csCode	95

csParam[0-1]	Not defined on entry. On exit, it contains the offset between the beginning of the 2K physical block and the first byte of the last read call.
csParam[2-10]	Not used during this Status call.

Status Return Codes:

noErr	The offset for the specified SCSI ID was returned.
statusErr	Prime was not previously called.

GetDriveType (csCode=96)

The purpose of this call is to return to the caller the type of CD-ROM drive located at the specified SCSI ID. Applications should begin using the new GetCDFeatures call instead of GetDriveType.

Input Parameters:

csCode	96

csParam[0]	Not defined on entry. On exit, it contains a code indicating the type of CD-ROM drive located at the specified SCSI ID. These codes are defined as follows:
		1	Drive is an AppleCD SC
		2	Drive is an AppleCD SC Plus / AppleCD 150
		3	Drive is an AppleCD 300 or AppleCD 300 Plus
csParam[1-10]	Not used during this Status call.

Status Return Codes:

noErr	The drive type for the specified SCSI ID was returned.
statusErr	The specified SCSI ID is not a CD-ROM drive.
WhoIsThere (csCode=97)

The purpose of this call is to return to the caller a list of devices that the CD-ROM driver is responsible for. It returns in csParam[0] a bit array, each member of which has a value of one if an Apple CD-ROM drive exists at the corresponding SCSI ID or a value of zero if it does not. The order of the bit array is the same as how Motorola orders bits in a byte; that is, the LSB (least significant bit) is the right-most bit, or the 20 bit. Since a maximum of 8 SCSI devices can be on the SCSI bus (addresses 0-7), the bit array takes up a byte, and will be located in the lower half of csParam[0], as shown here:

If SCSI Manager 4.3 is installed, the WhoIsThere call only shows CD-ROM drives available on the virtual SCSI bus. The ReturnDeviceIdent status call can be used to return a device ID for every CD-ROM drive controlled by the driver.

Input Parameters:

csCode	97

csParam[0]	Not defined on entry. On exit, it contains the above bit array.
csParam[1-10]	Not used during this Status call.

Status Return Codes:

noErr	This is the only possible status return code.

This call only works for a specified driver. Many third-party drivers have the same internal driver name as the Apple CD-ROM driver. (e.g. ".AppleCD") In order to detect all possible CD-ROM drives supported by all possible CD-ROM drivers, you should use the following sample code instead:

In C:

#define dRAMBased		0x0040

unsigned char WhereCDs()
{
  unsigned char where = 0;    /* assume no drives handled at beginning */
  short     scsiAddress;
  short     drvrRefNum;
  DCtlHandle    aDCtlEntry;
  StringPtr   aDriverName;
  StringPtr   appleDriverName = "\p.AppleCD";

  for (scsiAddress = 0; scsiAddress < 7; scsiAddress++) {
    drvrRefNum = -33 - scsiAddress;

    aDCtlEntry = GetDCtlEntry(drvrRefNum);
    if (aDCtlEntry != nil) {
      if ((**aDCtlEntry).dCtlFlags & dRAMBased)
        aDriverName = (StringPtr) ((*(DCtlPtr)aDCtlEntry).dCtlDriver+18);
      else
        aDriverName = (StringPtr)((**aDCtlEntry).dCtlDriver+18);
      if ( EqualString(aDriverName, appleDriverName, false, false) == true )
        where |= (1 << scsiAddress);
    }
  }
  return where;
}

In Pascal:

FUNCTION WhereCDs: Byte;

CONST
    kDriverName = '.AppleCD';  { Only recognize drivers whose names are '.AppleCD' }

  VAR
    where: LONGINT;
    scsiAddr: INTEGER;
    drvrRefNum: INTEGER;
    aDCtlEntry: DCtlHandle;
    aDriverName: StringPtr;

BEGIN
  where := 0;

  FOR scsiAddr := 0 TO 7 DO
    BEGIN
      drvrRefNum := -33 - scsiAddr;
      aDCtlEntry := GetDCtlEntry(drvrRefNum);   { Get the driver's control entry }
      IF aDCtlEntry <> NIL THEN                 { Is there a driver there? }
        BEGIN
        { Go find the driver's name }

          WITH aDCtlEntry^^ DO
            IF BAND(dCtlFlags, $0040) <> 0 THEN { Is it handle (RAM) based? }
              aDriverName := StringPtr(LONGINT(Handle(dCtlDriver)^) + 18)
            ELSE                                { It must be pointer (ROM) based. }
              aDriverName := StringPtr(LONGINT(dCtlDriver) + 18);

        { Is it named '.AppleCD'? }
          IF aDriverName^ = kDriverName THEN
            BSET(where, scsiAddr);
        END;
    END;

  WhereCDs := where;
END;

GetBlockSize (csCode=98)

The purpose of this call is to return to the caller the current block size of the CD-ROM drive.

Input Parameters:

csCode	98

csParam[0]	Not defined on entry. On exit, it contains the block size of the disc inserted in the specified SCSI ID.
csParam[1-10]	Not used during this Status call.

Status Return Codes:

noErr	The block size of the disc in the specified SCSI ID was returned.
offLinErr	The specified SCSI ID does not contain a disc.
ReturnDeviceIdent (csCode=120)

The purpose of this call is to return the SCSI Manager 4.3 DeviceIdent for the CD-ROM drive being controlled by this instance (entry in the unit table) of the driver. This call was first available in driver version 5.0.

Input Parameters:

csCode	120

csParam[0-10]	Unused on input. DeviceIdent is returned here.

Output Produced:

csParam[0-1]:	The DeviceIdent (Bus, SCSI ID, LUN)

Status Return Codes:

noErr	The DeviceIdent was returned.
GetCDFeatures (csCode=121)

The purpose of this call is to determine the features of this particular CD-ROM drive. Prior to driver version 5.0, this was done using the GetDriveType status call which returned a specific model of CD-ROM drive. This makes client code difficult to maintain since it must be modified each time a new CD-ROM drive is introduced. To alleviate this problem, the features of the device have been broken out into testable bits. A fixed point number containing the sustained transfer rate of the drive relative to an AppleCD 150 is also included. This information is returned in the following structure:

struct CDDeviceCharacteristics

{

unsigned char speedMajor; /* High byte of fixed point number containing

drive speed */

unsigned char speedMinor; /* Low byte of fixed point number containing drive

speed. AppleCD 300 Plus=2.0, AppleCD 150=1.0 */

unsigned short cdFlags; /* Flags for features of this drive */

unsigned short cdTransport; /* The type of transport mechanism this drive

uses */

};

typedef struct CDDeviceCharacteristics CDDeviceCharacteristics;

enum

{

cdFeatureFlagsMask = 0xFFFC, /* Flags are in the first 14 bits of cdFeatures */

cdTransportMask = 0x0003 /* Transport type is in last 2 bits of cdFeatures */

};

enum /* Flags for CD Features field */

{

cdMute = 0, /* Audio channels can be muted, i.e., audio play mode = 00xxb or xx00b */

/* Bits 1 and 2 are reserved */

cdLeftPlusRight = 3, /* Left and right channels can be mixed together, i.e., audio play mode = 11xxb or xx11b */

/* Bits 4 through 7 are reserved */

cdSCSI_2 = 8, /* Supports SCSI-2 CD-ROM Command Set */

cdStereoVolume = 9, /* Supports two independent volume levels (one for each audio channel)*/

cdDisconnect = 10, /* Drive supports SCSI disconnect/reconnect */

cdWriteOnce = 11, /* Drive is a write/once (CD-R) type drive */

cdMute_Mask = 1 << cdMute,

cdLeftPlusRight_Mask = 1 << cdLeftPlusRight,

cdSCSI_2_Mask = 1 << cdSCSI_2,

cdStereoVolume_Mask = 1 << cdStereoVolume,

cdDisconnect_Mask = 1 << cdDisconnect,

cdWriteOnce_Mask = 1 << cdWriteOnce

};

enum /* Transport types */

{

cdCaddy = 0, /* AppleCD 150, AppleCD 300 */

cdTray = 1, /* AppleCD 300 Plus */

cdLid = 2 /* PowerCD type device, e.g. no eject mechanism */

};

Input Parameters:

csCode	121

csParam[0-10]	Unused on input. CD-ROM drive features are returned here.

Output Produced:

csParam[0-1]:	The CD-ROM drive features as defined above.

Status Return Codes:

noErr	The CD-ROM drive features were returned.


Further Reference:

Tech Support
Technotes
Previous Technote | Contents | Next Technote


Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help